package cloud.lysky.java.on.async.completable_future;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.stream.Collectors;

/**
 * @author luoly
 * @describe
 * @date 2022-08-25 10:05
 **/
public class BestPriceFinder {


    List<Shop> shops = Arrays.asList(new Shop("BestPrice"),new Shop("LetsSaveBig"),new Shop("MyFavoriteShop"),new Shop("BuyItAll"));

    //自定义执行器
    private final Executor executor = Executors.newFixedThreadPool(Math.min(shops.size(), 100), new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread();
            t.setDaemon(true); //使用守护线程--这种方式不会阻止程序的关停
            return t;
        }
    });

    public List<String> findPrices(String product){
        return shops.stream().map(shop -> String.format("%s price is %.2f",shop.getName(),shop.getPrice(product))).collect(Collectors.toList());
    }

    public List<String> findPricesParallel(String product){
        return shops.parallelStream().map(shop -> String.format("%s price is %.2f",shop.getName(),shop.getPrice(product))).collect(Collectors.toList());
    }

    public List<String> findPricesCompletableFuture(String product){
        //使用CompletableFuture以异步方式计算每种商品的价格
        List<CompletableFuture<String>> completableFutures = shops.stream().map(shop -> CompletableFuture.supplyAsync(
                () -> String.format("%s price is %.2f", shop.getName(), shop.getPrice(product)))
        ).collect(Collectors.toList());

        //等待所有异步操作结束 返回计算好的值
        return completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
    }

    public List<String> findPricesCompletableFutureWithCustomExecutor(String product){
        //使用CompletableFuture以异步方式计算每种商品的价格
        List<CompletableFuture<String>> completableFutures = shops.stream().map(shop -> CompletableFuture.supplyAsync(
                () -> shop.getName()+ " price is" + shop.getPrice(product) ,executor)
        ).collect(Collectors.toList());

        //等待所有异步操作结束 返回计算好的值
        return completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
    }
}